// 农历数据
const LUNAR_INFO = [
  0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
  0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
  0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
  0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
  0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557
]

// 农历月份
const LUNAR_MONTHS = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊']
// 农历日期
const LUNAR_DAYS = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十',
  '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
  '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']

class LunarCalendar {
  constructor() {
    this.baseDate = new Date(1900, 0, 31)
  }

  // 公历转农历
  solarToLunar(year, month, day) {
    // 计算距离1900年1月31日的天数
    const date = new Date(year, month - 1, day)
    let offset = Math.floor((date - this.baseDate) / 86400000)

    // 计算农历年份
    let lunarYear = 1900
    let temp = 0
    for (let i = 0; i < LUNAR_INFO.length; i++) {
      temp = this.getLunarYearDays(LUNAR_INFO[i])
      if (offset < temp) {
        break
      }
      offset -= temp
      lunarYear++
    }

    // 计算农历月份
    let lunarMonth = 1
    let isLeap = false
    const yearInfo = LUNAR_INFO[lunarYear - 1900]
    const leapMonth = yearInfo & 0xf
    const monthDays = this.getMonthDays(yearInfo)
    
    for (let i = 0; i < 13; i++) {
      if (offset < monthDays[i]) {
        lunarMonth = i + 1
        break
      }
      offset -= monthDays[i]
      if (i + 1 === leapMonth) {
        if (!isLeap) {
          i--
          isLeap = true
        }
      }
    }

    // 计算农历日期
    const lunarDay = offset + 1

    return {
      year: lunarYear,
      month: lunarMonth,
      day: lunarDay,
      isLeap
    }
  }

  // 获取农历年的总天数
  getLunarYearDays(lunarYear) {
    let sum = 348
    for (let i = 0x8000; i > 0x8; i >>= 1) {
      sum += (lunarYear & i) ? 1 : 0
    }
    return sum + this.getLeapDays(lunarYear)
  }

  // 获取农历年闰月的天数
  getLeapDays(lunarYear) {
    if (this.getLeapMonth(lunarYear)) {
      return (lunarYear & 0x10000) ? 30 : 29
    }
    return 0
  }

  // 获取农历年闰月月份
  getLeapMonth(lunarYear) {
    return lunarYear & 0xf
  }

  // 获取农历年每月的天数
  getMonthDays(lunarYear) {
    const monthDays = []
    for (let i = 0; i < 13; i++) {
      monthDays[i] = (lunarYear & (0x10000 >> i)) ? 30 : 29
    }
    return monthDays
  }

  // 获取农历月份名称
  getLunarMonthName(month) {
    return LUNAR_MONTHS[month - 1]
  }

  // 获取农历日期名称
  getLunarDayName(day) {
    return LUNAR_DAYS[day - 1]
  }
}

// 创建单例实例
const lunar = new LunarCalendar()

// 导出模块
module.exports = lunar 